package com.rocky.project.mvc;

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequestWrapper;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ActionInvocation;
import com.opensymphony.xwork.ActionProxy;
import com.opensymphony.xwork.ValidationAware;
import com.opensymphony.xwork.util.LocalizedTextUtil;

public class FileUploadInterceptor extends
		com.opensymphony.webwork.interceptor.FileUploadInterceptor {

	/**
	 * 
	 */
	private static final long serialVersionUID = -166692942945242475L;
	private static final String DEFAULT_MESSAGE = "no.message.found";
	@SuppressWarnings("unchecked")
	public String intercept(ActionInvocation invocation) throws Exception {
		ActionContext ac = invocation.getInvocationContext();
		HttpServletRequest request = (HttpServletRequest) ac
				.get(ServletActionContext.HTTP_REQUEST);
		

		if (!(request instanceof MultiPartRequestWrapper)) {
			if (log.isDebugEnabled()) {
				ActionProxy proxy = invocation.getProxy();
				log.debug(getTextMessage("webwork.messages.bypass.request",
						new Object[] { proxy.getNamespace(),
								proxy.getActionName() }, ActionContext
								.getContext().getLocale()));
			}

			return invocation.invoke();
		}

		final Object action = invocation.getAction();
		ValidationAware validation = null;

		if (action instanceof ValidationAware) {
			validation = (ValidationAware) action;
		}

		MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request;

		if (multiWrapper.hasErrors()) {
			for (Iterator errorIter = multiWrapper.getErrors().iterator(); errorIter
					.hasNext();) {
				String error = (String) errorIter.next();

				if (validation != null) {
					validation.addActionError(error);
				}

				log.error(error);
			}
		}

		//encoding the parameters
		Map parameters = encodeParameter(ac.getParameters());

		// Bind allowed Files
		Enumeration fileParameterNames = multiWrapper.getFileParameterNames();
		while (fileParameterNames != null
				&& fileParameterNames.hasMoreElements()) {
			// get the value of this input tag
			String inputName = (String) fileParameterNames.nextElement();

			// get the content type
			String[] contentType = multiWrapper.getContentTypes(inputName);

			if (isNonEmpty(contentType)) {
				// get the name of the file from the input tag
				String[] fileName = multiWrapper.getFileNames(inputName);

				if (isNonEmpty(fileName)) {
					// Get a File object for the uploaded File
					File[] files = multiWrapper.getFiles(inputName);
					if (files != null) {
						for (int index = 0; index < files.length; index++) {
							getTextMessage("webwork.messages.current.file",
									new Object[] { inputName,
											contentType[index],
											fileName[index], files[index] },
									ActionContext.getContext().getLocale());

							if (acceptFile(files[0], contentType[0], inputName,
									validation, ac.getLocale())) {
								parameters.put(inputName, files);
								parameters.put(inputName + "ContentType",
										contentType);
								parameters
										.put(inputName + "FileName", fileName);
							}
						}
					}
				} else {
					log.error(getTextMessage("webwork.messages.invalid.file",
							new Object[] { inputName }, ActionContext
									.getContext().getLocale()));
				}
			} else {
				log.error(getTextMessage(
						"webwork.messages.invalid.content.type",
						new Object[] { inputName }, ActionContext.getContext()
								.getLocale()));
			}
		}

		// invoke action
		String result = invocation.invoke();

		// cleanup
		fileParameterNames = multiWrapper.getFileParameterNames();
		while (fileParameterNames != null
				&& fileParameterNames.hasMoreElements()) {
			String inputValue = (String) fileParameterNames.nextElement();
			File[] file = multiWrapper.getFiles(inputValue);
			for (int index = 0; index < file.length; index++) {
				File currentFile = file[index];
				log.info(getTextMessage("webwork.messages.removing.file",
						new Object[] { inputValue, currentFile }, ActionContext
								.getContext().getLocale()));

				if ((currentFile != null) && currentFile.isFile()) {
					currentFile.delete();
				}
			}
		}

		return result;
	}

	private Map encodeParameter(Map parameters) throws IOException {
		
		/*String encoding = "utf-8";
		if (Configuration.isSet(WebWorkConstants.WEBWORK_I18N_ENCODING)) {
			encoding = Configuration
					.getString(WebWorkConstants.WEBWORK_I18N_ENCODING);
		}

		byte[] value = new byte[] {};
		for (Iterator iter = parameters.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			if (parameters.get(key) != null
					&& parameters.get(key) instanceof String[]) {
				value = ((String[]) parameters.get(key))[0]
						.getBytes("ISO8859_1");
				parameters.put(key, new String(value, encoding));
			}
		}*/
		return parameters;
	}

	private static boolean isNonEmpty(Object[] objArray) {
		boolean result = false;
		for (int index = 0; index < objArray.length && !result; index++) {
			if (objArray[index] != null) {
				result = true;
			}
		}
		return result;
	}

	private String getTextMessage(String messageKey, Object[] args,
			Locale locale) {
		if (args == null || args.length == 0) {
			return LocalizedTextUtil.findText(this.getClass(), messageKey,
					locale);
		} else {
			return LocalizedTextUtil.findText(this.getClass(), messageKey,
					locale, DEFAULT_MESSAGE, args);
		}
	}

}
